import { Singleton } from "../core/Singleton";
import { ModuleInfo } from "./ModuleInfo";
import { ObjectPool } from "../utils/pools/ObjectPool";
import { ModuleLoader } from "./ModuleLoader";
import { IModule } from "./IModule";
import { Log } from "../debug/Log";
//class ModuleManager
    
    export  class ModuleManager extends Singleton
    {
        constructor()
        {
            
            super();this._modulesMap = new Map<any, any> /* flash.utils.Dictionary */();
            this._moduleList = new Array<any>();
            return;
        }

        public loadModuleInfo(arg1: Array<any>): void
        {
            var loc1=null;
            var loc2=0;
            while (loc2 < arg1.length) 
            {
                loc1 = arg1[loc2] as ModuleInfo;
                this._modulesMap[loc1.url] = loc1;
                ++loc2;
            }
            return;
        }

        /* internal  */getModuleInfo(arg1: string): ModuleInfo
        {
            return this._modulesMap[arg1] as ModuleInfo;
        }

        public loadModule(arg1: string): ModuleInfo
        {
            var loc1=this.getModuleInfo(arg1) as ModuleInfo;
            if (loc1) 
            {
                if (loc1.isLoaded) 
                {
                    this.loaderComplete(loc1);
                }
                else if (!loc1.isLoading) 
                {
                    this._moduleList.push(loc1);
                    loc1.isLoading = true;
                    if (this._isloading == false) 
                    {
                        this.loadNextModule();
                    }
                }
                return loc1;
            }
            throw new Error("没有该模块信息,请调用loadModuleInfo url=" + arg1);
        }

        /* internal  */loadNextModule(arg1: Object /* flash.system.LoaderContext */=null): void
        {
            var loc1=this._moduleList.shift() as ModuleInfo;
            if (loc1) 
            {
                this._isloading = true;
                this.loadModuleImpl(loc1, arg1);
            }
            else 
            {
                this._isloading = false;
            }
            return;
        }

        /* internal  */loadModuleImpl(arg1: ModuleInfo, arg2: Object /* flash.system.LoaderContext */=null): void
        {
            var loc1=ObjectPool.getObject(ModuleLoader);
            loc1.addEventListener(flash.events.Event.COMPLETE, this.onCompleteHandler);
            loc1.addEventListener(flash.events.ProgressEvent.PROGRESS, this.onProgressHandler);
            loc1.addEventListener(flash.events.IOErrorEvent.IO_ERROR, this.onIoErrorHandler);
            loc1.load(arg1.url, arg2);
            return;
        }

        /* internal  */loaderComplete(arg1: ModuleInfo): void
        {
            arg1.dispatchEvent(new Object /* flash.events.Event */(flash.events.Event.COMPLETE));
            return;
        }

        /* internal  */onCompleteHandler(arg1: Object /* flash.events.Event */): void
        {
            var loc1=arg1.target as ModuleLoader;
            loc1.removeEventListener(flash.events.Event.COMPLETE, this.onCompleteHandler);
            loc1.removeEventListener(flash.events.ProgressEvent.PROGRESS, this.onProgressHandler);
            loc1.removeEventListener(flash.events.IOErrorEvent.IO_ERROR, this.onIoErrorHandler);
            var loc2=this.getModuleInfo(loc1.url);
            loc2.isLoaded = true;
            loc2.isLoading = false;
            if (typeof loc1.content === "imodule") 
            {
                loc2.module = loc1.content as IModule;
            }
            else 
            {
                throw new Error("加载的不是模块，请实现IModule 接口");
            }
            this.loaderComplete(loc2);
            this.loadNextModule();
            this._tempModuleInfo = null;
            return;
        }

        /* internal  */onProgressHandler(arg1: Object /* flash.events.ProgressEvent */): void
        {
            var loc1=arg1.target as ModuleLoader;
            var loc2=this.getModuleInfo(loc1.url);
            if (loc2) 
            {
                loc2.dispatchEvent(arg1);
            }
            return;
        }

        /* internal  */onIoErrorHandler(arg1: Object /* flash.events.IOErrorEvent */): void
        {
            var loc1=arg1.target as ModuleLoader;
            var loc2=this.getModuleInfo(loc1.url);
            if (loc2) 
            {
                loc2.dispatchEvent(arg1);
                loc2.error = true;
                loc2.isLoaded = false;
                loc2.isLoading = false;
            }
            this.loadNextModule();
            Log.system("ModuleManager:" + arg1.text);
            return;
        }

        public static get instance(): ModuleManager
        {
            if (ModuleManager._instance == null) 
            {
                ModuleManager._instance = new ModuleManager();
            }
            return ModuleManager._instance;
        }

        private /* var */_modulesMap: Map<any, any> /* flash.utils.Dictionary */;

        private /* var */_moduleList: Array<any>;

        private /* var */_tempModuleInfo: ModuleInfo;

        private /* var */_isloading: Boolean=false;

        private static /* var */_instance: ModuleManager;
    }
